/*
 * The main menu screen
 */

#include <allegro.h>
#include "menu.h"
#include "draw/wingfx.h"
#include "main.h"
#include "lobby.h"
#include "resources/resources.h"
#include "util/ipc.h"
#include "util/log.h"

#define WND_BUTTONS_X 5
#define WND_BUTTONS_Y 120
#define WND_SUB_X (WND_BUTTONS_X+96)
#define WND_HOST_Y WND_BUTTONS_Y
#define WND_CLIENT_Y (WND_BUTTONS_Y) // +24

Window menu_wnd_buttons;
Window menu_wnd_host;
Window menu_wnd_client;
Button menu_btn_host;               // focus ID 1
Button menu_btn_client;             // focus ID 2
Button menu_btn_options;            // focus ID 3
Button menu_btn_exit;               // focus ID 4
Button menu_btn_host_ok;            // focus ID 7
Button menu_btn_client_ok;          // focus ID 11
Textfield menu_txt_host_nickname;   // focus ID 6
Textfield menu_txt_client_hoststr;  // focus ID 9
Textfield menu_txt_client_nickname; // focus ID 10
enum { MENU_VIEW_DEFAULT, MENU_VIEW_HOST, MENU_VIEW_CLIENT } menu_view;
static int focus; // Current user input focus. 0 = none

void menu_btnclick_host ();
void menu_btnclick_client ();
void menu_btnclick_options ();
void menu_btnclick_exit ();
void menu_btnclick_host_ok ();
void menu_btnclick_client_ok ();

static void focus_up ();
static void focus_down ();
static void focus_left ();
static void focus_right ();
	
void menu_init ()
{
	clear_keybuf ();
	show_mouse (screen);
	menu_wnd_buttons   = (Window) { bmp.winset, WINGFX_SET, WND_BUTTONS_X, WND_BUTTONS_Y, 12, 13 };
	menu_wnd_host      = (Window) { bmp.winset, WINGFX_SET, WND_SUB_X, WND_HOST_Y, 27, 8 };
	menu_wnd_client    = (Window) { bmp.winset, WINGFX_SET, WND_SUB_X, WND_CLIENT_Y, 27, 11 };
	menu_btn_host      = (Button) { bmp.winset, WINGFX_SET, WND_BUTTONS_X+12, WND_BUTTONS_Y+12, 9, 0, 0, fnt.sans, "Host Game" };
	menu_btn_client    = (Button) { bmp.winset, WINGFX_SET, WND_BUTTONS_X+12, WND_BUTTONS_Y+34, 9, 0, 0, fnt.sans, "Join Game" };
	menu_btn_options   = (Button) { bmp.winset, WINGFX_SET, WND_BUTTONS_X+12, WND_BUTTONS_Y+56, 9, 0, 0, fnt.sans, "Options" };
	menu_btn_exit      = (Button) { bmp.winset, WINGFX_SET, WND_BUTTONS_X+12, WND_BUTTONS_Y+78, 9, 0, 0, fnt.sans, "Quit" };
	menu_btn_host_ok   = (Button) { bmp.winset, WINGFX_SET, WND_SUB_X+80, WND_HOST_Y+36, 5, 0, 0, fnt.sans, "OK" };
	menu_btn_client_ok = (Button) { bmp.winset, WINGFX_SET, WND_SUB_X+80, WND_CLIENT_Y+60, 5, 0, 0, fnt.sans, "OK" };
	menu_txt_host_nickname   = (Textfield) { bmp.winset, WINGFX_SET, WND_SUB_X+80, WND_HOST_Y+12, 15, fnt.sans, "" };
	menu_txt_client_hoststr  = (Textfield) { bmp.winset, WINGFX_SET, WND_SUB_X+80, WND_CLIENT_Y+12, 15, fnt.sans, "localhost" };
	menu_txt_client_nickname = (Textfield) { bmp.winset, WINGFX_SET, WND_SUB_X+80, WND_CLIENT_Y+36, 15, fnt.sans, "AAA" };
	menu_view = MENU_VIEW_DEFAULT;
	focus = 0;
}

void menu_update ()
{
	int mouse_x, mouse_y;
	get_mouse (&mouse_x, &mouse_y);
	
	button_mouseevent (&menu_btn_host   , mouse_x, mouse_y, mouse_b & 1);
	button_mouseevent (&menu_btn_client , mouse_x, mouse_y, mouse_b & 1);
	button_mouseevent (&menu_btn_options, mouse_x, mouse_y, mouse_b & 1);
	button_mouseevent (&menu_btn_exit   , mouse_x, mouse_y, mouse_b & 1);
	
	if (button_was_clicked(&menu_btn_host   )) menu_btnclick_host ();
	if (button_was_clicked(&menu_btn_client )) menu_btnclick_client ();
	if (button_was_clicked(&menu_btn_options)) menu_btnclick_options ();
	if (button_was_clicked(&menu_btn_exit   )) menu_btnclick_exit ();
	
	if (keypressed()) {
		int key = readkey();
		int scan = key >> 8;
		int ascii = key & 0xff;
		
		if ((scan == KEY_DOWN) || (scan == KEY_TAB)) focus_down ();
		else if (scan == KEY_UP)                     focus_up ();
		else if (scan == KEY_LEFT)                   focus_left ();
		else if (scan == KEY_RIGHT)                  focus_right ();
		else if (scan == KEY_ENTER) {
			if ((focus == 1) || (focus == 2)) focus_right ();
			else if (focus == 3) menu_btnclick_options ();
			else if (focus == 4) menu_btnclick_exit ();
			else if ((focus >= 6) && (focus <= 7)) {
				if (menu_txt_host_nickname.caption[0] == '\0') {
					focus_left ();
				} else {
					menu_btnclick_host_ok ();
				}
			}
			else if ((focus >= 9) && (focus <= 11)) {
				if ((menu_txt_client_hoststr.caption[0] == '\0') || (menu_txt_client_nickname.caption[0] == '\0')) {
					focus_left ();
				} else {
					menu_btnclick_client_ok ();
				}
			}
		}
		else if (focus == 6)  textfield_type (&menu_txt_host_nickname, ascii);
		else if (focus == 9)  textfield_type (&menu_txt_client_hoststr, ascii);
		else if (focus == 10) textfield_type (&menu_txt_client_nickname, ascii);
	}
	
	switch (menu_view) {
		
	case MENU_VIEW_HOST:
		button_mouseevent (&menu_btn_host_ok, mouse_x, mouse_y, mouse_b & 1);
		if (button_was_clicked(&menu_btn_host_ok)) {
			menu_btnclick_host_ok ();
		} else
		if (textfield_is_clicked(&menu_txt_host_nickname, mouse_x, mouse_y, mouse_b & 1)) {
			focus = 6;
		}
		break;
	
	case MENU_VIEW_CLIENT:
		button_mouseevent (&menu_btn_client_ok, mouse_x, mouse_y, mouse_b & 1);
		if (button_was_clicked(&menu_btn_client_ok)) {
			menu_btnclick_client_ok ();
		} else
		if (textfield_is_clicked(&menu_txt_client_hoststr, mouse_x, mouse_y, mouse_b & 1)) {
			focus = 9;
		} else
		if (textfield_is_clicked(&menu_txt_client_nickname, mouse_x, mouse_y, mouse_b & 1)) {
			focus = 10;
		}
		break;
		
	default:
		break;
		
	}
}

void menu_draw ()
{
	acquire_bitmap(buffer);
	
	// Background image
	stretch_blit (bmp.menu, buffer, 
	              0, 0, bmp.menu->w, bmp.menu->h, 
	              0, 0, buffer->w, buffer->h);
	
	// Window and buttons
	window_draw (buffer, &menu_wnd_buttons);
	button_draw (buffer, &menu_btn_options, focus == 3);
	button_draw (buffer, &menu_btn_exit, focus == 4);
	
	switch (menu_view) {
		
	case MENU_VIEW_HOST:
		window_draw (buffer, &menu_wnd_host);
		textout_ex (buffer, fnt.sans, "Your Name:", WND_SUB_X+12, WND_HOST_Y+14, -1, -1);
		textfield_draw (buffer, &menu_txt_host_nickname, focus == 6);
		button_draw (buffer, &menu_btn_host_ok, focus == 7);
		button_draw (buffer, &menu_btn_host, 1);
		button_draw (buffer, &menu_btn_client, 0);
		break;
		
	case MENU_VIEW_CLIENT:
		window_draw (buffer, &menu_wnd_client);
		textout_ex (buffer, fnt.sans, "Server IP:", WND_SUB_X+12, WND_CLIENT_Y+14, -1, -1);
		textout_ex (buffer, fnt.sans, "Your Name:", WND_SUB_X+12, WND_CLIENT_Y+38, -1, -1);
		textfield_draw (buffer, &menu_txt_client_hoststr, focus == 9);
		textfield_draw (buffer, &menu_txt_client_nickname, focus == 10);
		button_draw (buffer, &menu_btn_client_ok, focus == 11);
		button_draw (buffer, &menu_btn_host, 0);
		button_draw (buffer, &menu_btn_client, 1);
		break;
		
	default:
		button_draw (buffer, &menu_btn_host, focus == 1);
		button_draw (buffer, &menu_btn_client, focus == 2);
		break;
		
	}
	
	release_bitmap(buffer);
}

void menu_cleanup ()
{
	show_mouse (NULL);
}

void menu_btnclick_host ()
{
	if (menu_view == MENU_VIEW_HOST) {
		focus = 0;
		menu_view = MENU_VIEW_DEFAULT;
	} else {
		focus = 6;
		menu_view = MENU_VIEW_HOST;
	}
}

void menu_btnclick_client ()
{
	if (menu_view == MENU_VIEW_CLIENT) {
		focus = 0;
		menu_view = MENU_VIEW_DEFAULT;
	} else {
		focus = 9;
		menu_view = MENU_VIEW_CLIENT;
	}
}

void menu_btnclick_options ()
{
	
}

void menu_btnclick_exit ()
{
	change_state (STATE_QUIT); // This will cause app exit
}

void menu_btnclick_host_ok ()
{
	if (!ipc_start_server ()) {
		log_fatal ("Failed to start server.");
	}
	
	const char* n = menu_txt_host_nickname.caption; // nickname
	lobby_configure ("localhost", n, 0);
	change_state (STATE_LOBBY);
}

void menu_btnclick_client_ok ()
{
	const char* s = menu_txt_client_hoststr.caption;  // server
	const char* n = menu_txt_client_nickname.caption; // nickname
	lobby_configure (s, n, 0);
	change_state (STATE_LOBBY);
}

static void focus_up ()
{
	if (focus > 7) { // client view
		if (focus == 8) {
			focus = 11;
		} else {
			focus = (focus - 9 + 2) % 3 + 9;
		}
	} else
	if (focus > 4) { // host view
		if (focus == 5) {
			focus = 7;
		} else {
			focus = (focus - 6 + 1) % 2 + 6;
		}
	} else { // default view
		if (focus == 0) {
			focus = 4;
		} else {
			focus = (focus - 1 + 3) % 4 + 1;
		}
	}
}

static void focus_down ()
{
	if (focus > 7) { // client view
		focus = (focus - 9 + 1) % 3 + 9;
	} else
	if (focus > 4) { // host view
		focus = (focus - 6 + 1) % 2 + 6;
	} else { // default view
		focus = (focus - 1 + 1) % 4 + 1;
	}
}

static void focus_left ()
{
	if (menu_view == MENU_VIEW_HOST) {
		focus = 1;
	} else
	if (menu_view == MENU_VIEW_CLIENT) {
		focus = 2;
	}
	menu_view = MENU_VIEW_DEFAULT;
}

static void focus_right ()
{
	if (focus == 1) {
		focus = 6;
		menu_view = MENU_VIEW_HOST;
	} else
	if (focus == 2) {
		focus = 9;
		menu_view = MENU_VIEW_CLIENT;
	}
}
